<?php
if(!defined('inside')) die('You do not have permission to execute this file directly.');

/**
* Session class file.
*
* @author Federico Ramirez <fedekiller@gmail.com>
* @link http://code.google.com/p/akaikiwi/
* @copyright Copyright &copy; 2008-2011 Federico Ramirez
* @license http://www.opensource.org/licenses/mit-license.php MIT Licence
*/

/*
* This class will handle custom akaikiwi sessions.
*/
class Session {
	private $preferences = array();

	/**
	 * Initialize with default values
	 */
	function __construct() {
		$config = AkaiKiwi::loadLib('Config');
		$this->preferences['match_ip']	=	FALSE;
		$this->preferences['duration']	=	3600;
		$this->preferences['useDB']		=	$config->get_item('sessionsUseDB');
		$this->preferences['table_name'] = $config->get_item('sessionsTable');
	}

	/**
	 * Initializes the class with the given parameters.
	 * @param Array $preferences
	 */
	public function init($preferences = array()) {
		foreach($preferences as $k => $v) {
			$this->preferences[$k] = $v;
		}
	}

	private function get_sid() {
		if(empty($_COOKIE['sid'])) {
			$config = AkaiKiwi::loadLib('Config');
			setcookie('sid', session_id(), time() + $this->preferences['duration'], str_replace('index.php', '', $config->get_item('basePath')));
			return session_id();
		} else {
			return $_COOKIE['sid'];
		}
	}

	/**
	 * Creates a new session
	 * @param String $name
	 * @param String $value
	 * @param boolean $flash
	 */
	public function add($name, $value, $flash = FALSE) {
		$config = AkaiKiwi::loadLib('Config');
		if($config->get_item('encodeSessions')) {
			$enc = AkaiKiwi::loadLib('Encrypt');
			$value = $enc->encode($value);
		}

		$value = base64_encode(serialize(array(
			'value'	=> $value,
			'ip'	=> $_SERVER['REMOTE_ADDR'],
			'flash'	=> $flash,
		)));

		if($this->preferences['useDB']) {
			$session = R::find($this->preferences['table_name'], 'name=? and sid=?', array($name, $this->get_sid()));
			if($session == NULL) {
				$session = R::dispense($this->preferences['table_name']);
			} else {
				$session = array_shift($session);
				$session = R::load($this->preferences['table_name'], $session->id);
			}
			$session->name = $name;
			$session->value = $value;
			$session->expires = time() + $this->preferences['duration'];
			$session->sid = $this->get_sid();
			R::store($session);

		} else {
			setcookie($name, $value, time() + $this->preferences['duration'], str_replace('index.php', '', $config->get_item('basePath')));
		}

		return TRUE;
	}

	/**
	 * Gets a session by name
	 * @param String $name
	 */
	public function get($name) {
		$value = NULL;

		if($this->preferences['useDB']) {
			$db = R::$adapter;
			$db->exec("delete from ".$this->preferences['table_name']." where expires < '".time()."'");

			$session = R::find($this->preferences['table_name'], 'name=? and sid=?', array($name, $this->get_sid()));
			if($session == NULL) {
				return NULL;
			}
			$session = array_shift($session);
			$value = $session->value;
		} else {
			if(!array_key_exists($name, $_COOKIE)) {
				return NULL;
			}
			$value = $_COOKIE[$name];
		}

		$arr = unserialize(base64_decode($value));
		$value = $arr['value'];
		$ip = $arr['ip'];
		$flash = $arr['flash'];

		if($this->preferences['match_ip']) {
			if($ip != $_SERVER['REMOTE_ADDR']) {
				return;
			}
		}

		$config = AkaiKiwi::loadLib('Config');
		if($config->get_item('encodeSessions')) {
			$enc = AkaiKiwi::loadLib('Encrypt');
			$value = $enc->decode($value);
		}

		if($flash) {
			remove($name);
		}

		return $value;
	}

	/**
	 * Removes a session
	 * @param String $name
	 */
	public function remove($name) {
		if($this->preferences['useDB']) {
			$db = R::$adapter;
			$db->exec("delete from ".$this->preferences['table_name']." where name='$name' and sid='".$this->get_sid()."'");
		} else {
			if(array_key_exists($name, $_COOKIE)) {
				$config = AkaiKiwi::loadLib('Config');
				setcookie($name, '', time() - 3600, str_replace('index.php', '', $config->get_item('basePath')));
			}
		}

		return TRUE;
	}
}
